from flask import Blueprint, request
from flask_restful import Resource
from app.model import (
    TestSuite, Coordinate, BaseStep, Module, TestCase, 
    CustomStepType, StepType, CustomStep, TestCaseStep,
    test_suite_pre_steps, test_suite_case_pre_steps
)
from flask import Blueprint, request
from app.utils.response_handler import response_with_handler, success_response, error_response
from app.model import db

data_bp = Blueprint('data', __name__)

@data_bp.route('/export/<int:suite_id>', methods=['GET'])
@response_with_handler
def export_testcase_data(suite_id):
    """导出测试用例数据，供原框架使用"""
    try:
        suite = TestSuite.query.get_or_404(suite_id)
        test_data = {
            'suite_name': suite.suite_name,
            'run_times': suite.run_times,
            'cases': []
        }
        
        # 1. 添加套件前置步骤
        suite_pre = {
            'case_name': '套件前置',
            'steps': []
        }
        # 直接从关联表获取套件前置步骤
        stmt = test_suite_pre_steps.select().where(
            test_suite_pre_steps.c.suite_id == suite.id
        ).order_by(test_suite_pre_steps.c.step_order)
        
        pre_steps = db.session.execute(stmt).fetchall()
        for step in pre_steps:
            if step.is_custom:
                # 获取自定义步骤
                custom_step = CustomStep.query.get(step.step_id)
                if custom_step:
                    suite_pre['steps'].append({
                        'module': 'custom',
                        'step': custom_step.step_name,
                        'parameters': None
                    })
            else:
                # 获取基础步骤
                base_step = BaseStep.query.get(step.step_id)
                if base_step and base_step.module:
                    suite_pre['steps'].append({
                        'module': base_step.module.name,
                        'step': base_step.step_name,
                        'parameters': None
                    })
        test_data['cases'].append(suite_pre)
        
        # 2. 添加用例前置步骤
        case_pre = {
            'case_name': '用例前置',
            'steps': []
        }
        # 直接从关联表获取用例前置步骤
        stmt = test_suite_case_pre_steps.select().where(
            test_suite_case_pre_steps.c.suite_id == suite.id
        ).order_by(test_suite_case_pre_steps.c.step_order)
        
        pre_steps = db.session.execute(stmt).fetchall()
        for step in pre_steps:
            if step.is_custom:
                custom_step = CustomStep.query.get(step.step_id)
                if custom_step:
                    case_pre['steps'].append({
                        'module': 'custom',
                        'step': custom_step.step_name,
                        'parameters': None
                    })
            else:
                base_step = BaseStep.query.get(step.step_id)
                if base_step and base_step.module:
                    case_pre['steps'].append({
                        'module': base_step.module.name,
                        'step': base_step.step_name,
                        'parameters': None
                    })
        test_data['cases'].append(case_pre)
        
        # 3. 添加测试用例
        for case in suite.cases:
            case_data = {
                'case_name': case.case_name,
                'steps': []
            }
            # 获取用例的所有步骤
            case_steps = TestCaseStep.query.filter_by(test_case_id=case.id).order_by(TestCaseStep.step_order).all()
            
            for case_step in case_steps:
                # 处理基础步骤
                if case_step.step_id:
                    base_step = BaseStep.query.get(case_step.step_id)
                    if base_step and base_step.module:
                        case_data['steps'].append({
                            'module': base_step.module.name,
                            'step': base_step.step_name,
                            'parameters': case_step.parameters or ''
                        })
                # 处理自定义步骤
                elif case_step.custom_step_id:
                    custom_step = CustomStep.query.get(case_step.custom_step_id)
                    if custom_step:
                        case_data['steps'].append({
                            'module': 'custom',
                            'step': custom_step.step_name,
                            'parameters': case_step.parameters or ''
                        })
            
            test_data['cases'].append(case_data)
            
        return success_response(test_data)
    except Exception as e:
        return error_response(f"获取数据失败: {str(e)}", code=500)

@data_bp.route('/base_steps/all', methods=['GET'])
@response_with_handler
def get_all_base_steps():
    """获取所有基础步骤数据（包含坐标和模块信息）"""
    try:
        # 获取所有模块
        modules = Module.query.all()
        
        # 按模块组织数据
        data = {}
        
        for module in modules:
            module_data = {
                'module_name': module.name,
                'module_id': module.id,
                'description': module.description,
                'coordinates': {},
                'base_steps': []
            }
            
            # 获取该模块的所有坐标
            coords = Coordinate.query.filter_by(module_id=module.id).all()
            for coord in coords:
                module_data['coordinates'][coord.element_name] = {
                    'id': coord.id,
                    'x': coord.x_coord,
                    'y': coord.y_coord,
                    'description': coord.description
                }
            
            # 获取该模块的所有基础步骤
            steps = BaseStep.query.filter_by(module_id=module.id).all()
            for step in steps:
                step_data = {
                    'id': step.id,
                    'name': step.step_name,
                    'type': step.step_type,
                    'description': step.description,
                    'coordinate': module_data['coordinates'].get(step.coordinate.element_name) if step.coordinate else None
                }
                module_data['base_steps'].append(step_data)
            
            data[module.name] = module_data
        
        return success_response(data)
    except Exception as e:
        return error_response(f"获取数据失败: {str(e)}", code=500) 

@data_bp.route('/generate_shell/<int:suite_id>', methods=['GET'])
@response_with_handler
def generate_shell_script(suite_id):
    """生成测试套件的shell脚本"""
    try:
        suite = TestSuite.query.get_or_404(suite_id)
        script_lines = ["#!/bin/sh\n"]
        prefix = ""
        
        # 添加套件前置步骤
        if suite.suite_pre_steps:
            script_lines.append(f"{prefix}echo [$(date +\"%H:%M:%S\")]: 套件前置步骤开始\n")
            for pre_step in suite.suite_pre_steps:
                base_step = BaseStep.query.get(pre_step.id)
                script_lines.append(generate_step_script(base_step, prefix))
            script_lines.append(f"{prefix}echo [$(date +\"%H:%M:%S\")]: 套件前置步骤结束\n\n")
        
        # 按模块组织用例
        module_cases = {}
        for case in suite.cases:
            if case.module_id not in module_cases:
                module_cases[case.module_id] = []
            module_cases[case.module_id].append(case)
        
        # 处理每个模块的用例
        for module_id, cases in module_cases.items():
            module = Module.query.get(module_id)
            script_lines.append(f"{prefix}echo [$(date +\"%H:%M:%S\")]: {module.name}模块测试开始\n")
            
            # 处理每个用例
            for case in cases:
                # 用例前置步骤
                if case.pre_steps:
                    script_lines.append(f"{prefix}echo [$(date +\"%H:%M:%S\")]: {case.case_name}前置步骤开始\n")
                    for pre_step in case.pre_steps:
                        base_step = BaseStep.query.get(pre_step.id)
                        script_lines.append(generate_step_script(base_step, prefix))
                    script_lines.append(f"{prefix}echo [$(date +\"%H:%M:%S\")]: {case.case_name}前置步骤结束\n")
                
                # 用例步骤
                script_lines.append(f"{prefix}echo [$(date +\"%H:%M:%S\")]: {case.case_name}用例测试开始\n")
                for step in case.steps:
                    base_step = BaseStep.query.get(step.id)
                    script_content = generate_step_script(base_step, prefix, step.parameters)
                    script_lines.append(script_content)
                script_lines.append(f"{prefix}echo [$(date +\"%H:%M:%S\")]: {case.case_name}用例测试结束\n\n")
            
            script_lines.append(f"{prefix}echo [$(date +\"%H:%M:%S\")]: {module.name}模块测试结束\n\n")
        
        return success_response({
            'script_content': ''.join(script_lines),
            'suite_name': suite.suite_name
        })
    except Exception as e:
        return error_response(f"生成脚本失败: {str(e)}", code=500)

def generate_step_script(base_step, prefix="", parameters=None):
    """生成单个步骤的脚本内容"""
    if base_step.step_type == StepType.CUSTOM.value:
        return generate_custom_step_script(base_step.step_name, prefix, parameters)
    
    # 处理普通步骤...
    coordinate = Coordinate.query.get(base_step.coordinate_id) if base_step.coordinate_id else None
    
    if not coordinate:
        return f"{prefix}# Step without coordinate: {base_step.step_name}\n"
        
    if base_step.step_name == "点击��键":
        return f"{prefix}mousetool MOVE {coordinate.x_coord} {coordinate.y_coord}\n" \
               f"{prefix}mousetool CTRL MOUSE_LEFT_DOWN;mousetool CTRL MOUSE_LEFT_UP\n"
    elif base_step.step_name == "点击右键":
        return f"{prefix}mousetool MOVE {coordinate.x_coord} {coordinate.y_coord}\n" \
               f"{prefix}mousetool CTRL MOUSE_RIGHT_DOWN;mousetool CTRL MOUSE_RIGHT_UP\n"
    # ... 其他步骤类型的处理

def generate_custom_step_script(step_name, prefix="", parameters=None):
    """生成自定义步骤的脚本内容"""
    if step_name == CustomStepType.SLEEP.value:
        return f"{prefix}sleep {parameters or 1}\n"
    elif step_name == CustomStepType.FOR_LOOP.value:
        return f"{prefix}for i in `seq {parameters or 1}`\ndo\n"
    elif step_name == CustomStepType.ASSERT.value:
        return f"{prefix}if [ {parameters or 'true'} ]; then\n"
    elif step_name == CustomStepType.LEFT_DOWN.value:
        return f"{prefix}mousetool CTRL MOUSE_LEFT_DOWN\n"
    elif step_name == CustomStepType.LEFT_UP.value:
        return f"{prefix}mousetool CTRL MOUSE_LEFT_UP\n"
    elif step_name == CustomStepType.RIGHT_DOWN.value:
        return f"{prefix}mousetool CTRL MOUSE_RIGHT_DOWN\n"
    elif step_name == CustomStepType.RIGHT_UP.value:
        return f"{prefix}mousetool CTRL MOUSE_RIGHT_UP\n"
    
    return f"{prefix}# Custom step: {step_name} {parameters or ''}\n"

@data_bp.route('/custom_steps', methods=['GET'])
@response_with_handler
def get_custom_steps():
    """获取所有自定义步骤"""
    try:
        custom_steps = []
        # 先从数据库中获取或创建自定义步骤
        for name, member in CustomStepType.__members__.items():
            # 查找或创建自定义步骤
            custom_step = CustomStep.query.filter_by(step_name=member.value).first()
            if not custom_step:
                custom_step = CustomStep(
                    step_name=member.value,
                    step_type=StepType.CUSTOM.value,
                    description=f'自定义步骤 - {member.value}'
                )
                db.session.add(custom_step)
                
        db.session.commit()
        
        # 重新查询���有自定义步骤
        all_custom_steps = CustomStep.query.all()
        custom_steps = [{
            'id': step.id,
            'step_name': step.step_name,
            'step_type': step.step_type,
            'description': step.description
        } for step in all_custom_steps]
            
        return success_response(custom_steps)
    except Exception as e:
        db.session.rollback()
        return error_response(f"获取自定义步骤失败: {str(e)}", code=500)

@data_bp.route('/steps/all', methods=['GET'])
@response_with_handler
def get_all_steps():
    """获取所有步骤（包括模块步骤和自定义步骤）"""
    try:
        # 获取模块步骤
        modules = Module.query.all()
        module_steps = {}
        
        for module in modules:
            steps = BaseStep.query.filter_by(module_id=module.id).all()
            module_steps[module.name] = [{
                'id': step.id,
                'step_name': step.step_name,
                'step_type': StepType.NORMAL.value,
                'description': step.description
            } for step in steps]
            
        # 获取自定义步骤
        custom_steps = []
        all_custom_steps = CustomStep.query.all()
        for step in all_custom_steps:
            custom_step = {
                'id': step.id,
                'step_name': step.step_name,
                'step_type': StepType.CUSTOM.value,
                'description': step.description
            }
            custom_steps.append(custom_step)
            
        return success_response({
            'module_steps': module_steps,
            'custom_steps': custom_steps
        })
    except Exception as e:
        return error_response(f"获取步骤��败: {str(e)}", code=500) 